module dice.render.canvas;

import dice.render.painter;
import dice.render.structs;

import cr = dice.render.cairo;
import str = std.string;

/** A surface that can be painted on */
abstract class Canvas
{
	/** Get a painter object that operates on this canvas */
	abstract Painter painter();
}

/** An in-memory RGBA pixel-based canvas (painter implemented with cairo) */
class Pixmap : Canvas
{
	int width, height;
	Pixel[] pixels;
	
	this (int w, int h)
	{
		pixels = new Pixel[w*h];
		width = w;
		height = h;
	}
	
	cr.Surface* cairoClone ()
	{
		return cr.cairo_image_surface_create_for_data(cast(char*)cast(void*)pixels.ptr, cr.Format.ARGB32, width, height, width*4);
	}
	
	Painter painter ()
	{
		cr.Surface* s = cr.cairo_image_surface_create_for_data(cast(char*)cast(void*)pixels.ptr, cr.Format.ARGB32, width, height, width*4);
		Painter p = new CairoPainter(this, cr.cairo_create(s));
		cr.cairo_surface_destroy(s);
		return p;
	}
	
	void writePNG (char[] f)
	{
		cr.Surface* s = cr.cairo_image_surface_create_for_data(cast(char*)cast(void*)pixels.ptr, cr.Format.ARGB32, width, height, width*4);
		cr.cairo_surface_write_to_png(s, str.toStringz(f));
		cr.cairo_surface_destroy(s);
	}
}
